package com.hisense.proxy.busitrans.controller.zndz;

import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hisense.proxy.busitrans.vo.zndz.RuleSetVO;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

@Controller
@RequestMapping("/ncc/zndz/ruleset")
@Slf4j
public class RuleSetExcelController {

	private final Pattern pattern = Pattern.compile("^[a-zA-Z0-9;；\\-]+$");
	 
	
	@PostMapping("upload")
	@ResponseBody
	@SneakyThrows
	public JSONObject upload(MultipartFile file, HttpServletResponse response) {
		List<RuleSetVO> excelContent = EasyExcel.read(file.getInputStream())
        .head(RuleSetVO.class)
        .headRowNumber(2)
        .sheet().doReadSync();
		
		if (excelContent != null && excelContent.size() == 0) {
    		return buildSuccessResponse(new ArrayList<RuleSetVO>());
    	}
		
    	
		log.debug("上传了 {} 条规则", excelContent.size());
    	
		try {
			checkAndTrim(excelContent);
		} catch (Exception e) {
			return buildFailResponse(e.getMessage());
		}
		
        return buildSuccessResponse(excelContent);
	}

	@PostMapping("download")
	@SneakyThrows
	public void download(HttpServletRequest request, HttpServletResponse response, @RequestBody List<RuleSetVO> ruleSet) {
		
		String agent = request.getHeader("User-agent");
		if (agent.indexOf("Firefox") != -1) {
			response.addHeader("content-disposition",
					"attachment;filename*=UTF-8''" + URLEncoder.encode("规则设定表.xlsx", "UTF-8"));
		} else {
			response.addHeader("content-Disposition",
					"attachment;fileName=" + URLEncoder.encode("规则设定表.xlsx", "utf-8"));
		}
		
		InputStream templateStream = null;
		try {
			templateStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("zndz/规则设定模板.xlsx");
			EasyExcel.write(response.getOutputStream()).withTemplate(templateStream).sheet().doFill(ruleSet);
		} catch (Exception e) {
			response.addHeader("content-type", "application/json;utf-8");
			response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
			String msg = e.getCause() == null ? e.getMessage() : e.getCause().getMessage();
			try {
				response.getWriter().write(JSON.toJSONString(buildFailResponse(msg)));
			} catch (IOException e1) {
			}
		} finally {
			if (templateStream != null) {
				try {
					templateStream.close();
				} catch (Exception e) {}
			}
		}
	}
	
	
	@SneakyThrows
	private void checkAndTrim(List<RuleSetVO> ruleSet) {
	    
		if (ruleSet == null || ruleSet.size() == 0) {
			return;
		}
		
		Iterator<RuleSetVO> iterator = ruleSet.iterator();
		
		while (iterator.hasNext()) {
			RuleSetVO ruleSetVO = iterator.next();
			String no = ruleSetVO.getNo();
			String terminalNo = ruleSetVO.getTerminalNo();
			String bankAccountNo = ruleSetVO.getBankAccountNo();
			String merchantNo = ruleSetVO.getMerchantNo();
			String projectGuid = ruleSetVO.getProjectGuid();
			
			
			if (StringUtils.isEmpty(no) && StringUtils.isEmpty(terminalNo) && StringUtils.isEmpty(bankAccountNo) && StringUtils.isEmpty(merchantNo) && StringUtils.isEmpty(projectGuid)) {
				iterator.remove();
				continue;
			}
			
			if (StringUtils.isEmpty(no)) {
				throw new Exception("存在序号为空，请检查！");
			}
			if (StringUtils.isEmpty(bankAccountNo)) {
				throw new Exception("第"+no+"行的银行账号为空，请检查！");
			}
			
			if (StringUtils.isEmpty(terminalNo) && StringUtils.isEmpty(projectGuid)) {
				throw new Exception("第"+no+"行的终端号和项目分期ID不能同时为空，请检查！");

			} 
			
			
			if (!pattern.matcher(terminalNo).matches()) {
				throw new Exception(buildPatternCheckException(ruleSetVO, "智能POS机终端号", terminalNo));
			}
			
			if (!pattern.matcher(bankAccountNo).matches()) {
				throw new Exception(buildPatternCheckException(ruleSetVO, "银行账号", bankAccountNo));
			}
			
			if (!pattern.matcher(merchantNo).matches()) {
				throw new Exception(buildPatternCheckException(ruleSetVO, "智能POS商户号", merchantNo));
			}
			
			if (!pattern.matcher(projectGuid).matches()) {
				throw new Exception(buildPatternCheckException(ruleSetVO, "项目对应分期id", projectGuid));
			}
			
			no = no.replaceAll(" ", "");
			terminalNo = terminalNo.replaceAll(" ", "");
			bankAccountNo = bankAccountNo.replaceAll(" ", "");
			merchantNo = merchantNo.replaceAll(" ", "");
			projectGuid = projectGuid.replaceAll(" ", "");
			
		}		
	}
	
	
	private String buildPatternCheckException(RuleSetVO ruleSetVO, String key, String value) {
		StringBuilder builder = new StringBuilder("字段 ");
		builder.append(key)
		.append(" 存在非法字符，位于序号 ")
		.append(ruleSetVO.getNo())
		.append(" , 允许的字符为 : 大小写英文字母、数字");

		if ("项目对应分期id".equals(key)) {
			builder.append("、 中英文分号。");
		} else if ("银行账号".equals(key)) {
			builder.append("、短横线(-)。");
		}
		
		return builder.toString();
		
	}

	private JSONObject buildSuccessResponse(Object data) {
		JSONObject res = new JSONObject();
		res.put("code", 1000);
		res.put("message", "success");
		res.put("data", data);
		
		return res;
	}
	
	private JSONObject buildFailResponse(String message) {
		JSONObject res = new JSONObject();
		res.put("code", 500);
		res.put("message", message);
		res.put("data", null);
		
		return res;
	}
	
}
